home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
FTPCLI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-10
|
19KB
|
784 lines
/* FTP client (interactive user) code */
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "netuser.h"
#include "icmp.h"
#include "timer.h"
#include "tcp.h"
#include "ftp.h"
#include "session.h"
#include "cmdparse.h"
#ifdef ATARI_ST
# ifdef __TURBOC__
# include <tos.h>
# else
# include <osbind.h>
# endif
#endif
extern struct session *current;
extern char nospace[];
extern char badhost[];
static char notsess[] = "Not an FTP session!\n";
static char cantwrite[] = "Can't write %s\n";
static char cantread[] = "Can't read %s\n";
#if (defined(MSC) || (defined(ATARI_ST) && defined(__TURBOC__)))
static int sndftpmsg(struct ftp *ftp,char *fmt,...);
#endif
int donothing(),doftpcd(),dolist(),doget(),dols(),doput(),dotype(),doabort(),
domkdir(),dormdir(),dotput();
struct cmds ftpabort[] = {
"", donothing, 0, NULLCHAR, NULLCHAR,
"abort", doabort, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0, "Only valid command is \"abort\"", NULLCHAR
};
struct cmds ftpcmds[] = {
"", donothing, 0, NULLCHAR, NULLCHAR,
"cd", doftpcd, 2, "<directory>", NULLCHAR,
"dir", dolist, 0, NULLCHAR, NULLCHAR,
"list", dolist, 0, NULLCHAR, NULLCHAR,
"get", doget, 2, "<remotefile> [<localfile>]", NULLCHAR,
"ls", dols, 0, NULLCHAR, NULLCHAR,
"mkdir", domkdir, 2, "<directory>", NULLCHAR,
"nlst", dols, 0, NULLCHAR, NULLCHAR,
"rmdir", dormdir, 2, "<directory>", NULLCHAR,
"put", doput, 2, "<localfile> [<remotefile>]", NULLCHAR,
"type", dotype, 0, NULLCHAR, NULLCHAR,
#if (defined(MSDOS))
"tput", dotput, 2, "<localspec>", NULLCHAR,
#endif
#if (defined(ATARI_ST))
"tput", dotput, 2, "<localspec> [x]", NULLCHAR,
#endif
NULLCHAR, NULLFP, 0, NULLCHAR, NULLCHAR
};
/* Handle top-level FTP command */
doftp(argc,argv)
int argc;
char *argv[];
{
int32 resolve();
int ftpparse();
void ftpccr(),ftpccs();
struct session *s;
struct ftp *ftp,*ftp_create();
struct tcb *tcb;
struct socket lsocket,fsocket;
char tos = 0;
lsocket.address = ip_addr;
lsocket.port = lport++;
if((fsocket.address = resolve(argv[1])) == 0){
printf(badhost,argv[1]);
return 1;
}
if(argc < 3)
fsocket.port = FTP_PORT;
else {
if((fsocket.port = atoi(argv[2])) == 0)
fsocket.port = FTP_PORT;
tos = get_tos(argv[3]);
}
/* Allocate a session control block */
if((s = newsession()) == NULLSESSION){
printf("Too many sessions\n");
return 1;
}
current = s;
if((s->name = malloc((unsigned)strlen(argv[1])+1)) != NULLCHAR)
strcpy(s->name,argv[1]);
s->type = FTP;
s->parse = ftpparse;
/* Allocate an FTP control block */
if((ftp = ftp_create(0)) == NULLFTP){
s->type = FREE;
printf(nospace);
return 1;
}
ftp->state = COMMAND_STATE;
s->cb.ftp = ftp; /* Downward link */
ftp->session = s; /* Upward link */
/* Now open the control connection */
tcb = open_tcp(&lsocket,&fsocket,TCP_ACTIVE,
0,ftpccr,NULLVFP,ftpccs,tos,(char *)ftp);
ftp->control = tcb;
go();
return 0;
}
/* Parse user FTP commands */
int
ftpparse(line,len)
char *line;
int16 len;
{
struct mbuf *bp;
if(current->cb.ftp->state != COMMAND_STATE){
/* The only command allowed in data transfer state is ABORT */
if(cmdparse(ftpabort,line) == -1){
printf("Transfer in progress; only ABORT is acceptable\n");
}
fflush(stdout);
return;
}
/* Save it now because cmdparse modifies the original */
bp = qdata(line,len);
if(cmdparse(ftpcmds,line) == -1){
/* Send it direct */
if(bp != NULLBUF)
send_tcp(current->cb.ftp->control,bp);
else
printf(nospace);
} else {
free_p(bp);
}
fflush(stdout);
}
/* Handle null line to avoid trapping on first command in table */
static
int
donothing(argc,argv)
int argc;
char *argv[];
{
return 0;
}
/* Translate 'cd' to 'cwd' for convenience */
static
int
doftpcd(argc,argv)
int argc;
char *argv[];
{
register struct ftp *ftp;
ftp = current->cb.ftp;
return sndftpmsg(ftp,"CWD %s\r\n",argv[1]);
}
/* Translate 'mkdir' to 'xmkd' for convenience */
static
int
domkdir(argc,argv)
int argc;
char *argv[];
{
register struct ftp *ftp;
ftp = current->cb.ftp;
return sndftpmsg(ftp,"XMKD %s\r\n",argv[1]);
}
/* Translate 'rmdir' to 'xrmd' for convenience */
static
int
dormdir(argc,argv)
int argc;
char *argv[];
{
register struct ftp *ftp;
ftp = current->cb.ftp;
return sndftpmsg(ftp,"XRMD %s\r\n",argv[1]);
}
/* Handle "type" command from user */
static
int
dotype(argc,argv)
int argc;
char *argv[];
{
register struct ftp *ftp;
ftp = current->cb.ftp;
if(argc < 2){
switch(ftp->type){
case IMAGE_TYPE:
printf("Image\n");
break;
case ASCII_TYPE:
printf("Ascii\n");
break;
}
return 0;
}
switch(*argv[1]){
case 'i':
case 'b':
ftp->type = IMAGE_TYPE;
sndftpmsg(ftp,"TYPE I\r\n");
break;
case 'a':
ftp->type = ASCII_TYPE;
sndftpmsg(ftp,"TYPE A\r\n");
break;
case 'l':
if (argc > 2){
ftp->type = IMAGE_TYPE;
sndftpmsg(ftp,"TYPE L %s\r\n",argv[2]);
break;
}
/* no arg after TYPE L, drop in default
instead of generating BUS ERROR on Atari ST (and others) */
default:
printf("Invalid type %s\n",argv[1]);
return 1;
}
return 0;
}
/* Start receive transfer. Syntax: get <remote name> [<local name>] */
static
doget(argc,argv)
int argc;
char *argv[];
{
void ftpdr(),ftpcds();
char *remotename,*localname;
register struct ftp *ftp;
char *mode;
if((ftp = current->cb.ftp) == NULLFTP){
printf(notsess);
return 1;
}
remotename = argv[1];
if(argc < 3)
localname = remotename;
else
localname = argv[2];
if(ftp->fp != NULLFILE && ftp->fp != stdout)
fclose(ftp->fp);
if(ftp->type == IMAGE_TYPE)
mode = binmode[WRITE_BINARY];
else
mode = "w";
if((ftp->fp = fopen(localname,mode)) == NULLFILE){
printf(cantwrite,localname);
return 1;
}
ftp->state = RECEIVING_STATE;
ftpsetup(ftp,ftpdr,NULLVFP,ftpcds);
/* Generate the command to start the transfer */
return sndftpmsg(ftp,"RETR %s\r\n",remotename);
}
/* List remote directory. Syntax: dir <remote directory/file> [<local name>] */
static
dolist(argc,argv)
int argc;
char *argv[];
{
void ftpdr(),ftpcds();
register struct ftp *ftp;
if((ftp = current->cb.ftp) == NULLFTP){
printf(notsess);
return 1;
}
if(ftp->fp != NULLFILE && ftp->fp != stdout)
fclose(ftp->fp);
if(argc < 3){
ftp->fp = stdout;
} else if((ftp->fp = fopen(argv[2],"w")) == NULLFILE){
printf(cantwrite,argv[2]);
return 1;
}
ftp->state = RECEIVING_STATE;
ftpsetup(ftp,ftpdr,NULLVFP,ftpcds);
/* Generate the command to start the transfer
* It's done this way to avoid confusing the 4.2 FTP server
* if there's no argument
*/
if(argc > 1)
return sndftpmsg(ftp,"LIST %s\r\n",argv[1]);
else
return sndftpmsg(ftp,"LIST\r\n");
}
/* Abbreviated (name only) list of remote directory.
* Syntax: ls <remote directory/file> [<local name>]
*/
static
dols(argc,argv)
int argc;
char *argv[];
{
void ftpdr(),ftpcds();
register struct ftp *ftp;
if((ftp = current->cb.ftp) == NULLFTP){
printf(notsess);
return 1;
}
if(ftp->fp != NULLFILE && ftp->fp != stdout)
fclose(ftp->fp);
if(argc < 3){
ftp->fp = stdout;
} else if((ftp->fp = fopen(argv[2],"w")) == NULLFILE){
printf(cantwrite,argv[2]);
return 1;
}
ftp->state = RECEIVING_STATE;
ftpsetup(ftp,ftpdr,NULLVFP,ftpcds);
/* Generate the command to start the transfer */
if(argc > 1)
return sndftpmsg(ftp,"NLST %s\r\n",argv[1]);
else
return sndftpmsg(ftp,"NLST\r\n");
}
/* Start transmit. Syntax: put <local name> [<remote name>] */
static
doput(argc,argv)
int argc;
char *argv[];
{
void ftpdt(),ftpcds();
char *remotename,*localname;
char *mode;
struct ftp *ftp;
if((ftp = current->cb.ftp) == NULLFTP){
printf(notsess);
return 1;
}
localname = argv[1];
if(argc < 3)
remotename = localname;
else
remotename = argv[2];
if(ftp->fp != NULLFILE && ftp->fp != stdout)
fclose(ftp->fp);
if(ftp->type == IMAGE_TYPE)